`
https://leetcode.cn/problems/minimum-operations-to-reduce-x-to-zero/
`

/**
 * @param {number[]} nums
 * @param {number} x
 * @return {number}
 */
var minOperations = function (nums, x) {
  const n = nums.length

  // 题目是从两边开始拿元素，这样的话中间就会剩下一个子数组
  // 那么便可以把题目等价为寻找和为 sum(x) - x 的最长子数组

  // 计算前缀和
  const prefix = new Array(n + 1)
  prefix[0] = 0
  for (let i = 1; i < prefix.length; i++) {
    prefix[i] = prefix[i - 1] + nums[i - 1]
  }

  const sum = prefix[prefix.length - 1]
  const need = sum - x

  // 前缀和 + 哈希表无法处理整个数组和为 x 的情况
  // 这里需要特判一下
  if (need === 0) return n

  let res = -1

  // 记录前缀和对应的索引
  const valToIdx = new Map()

  for (let i = 0; i < prefix.length; i++) {
    // 要达成条件所需要的值
    const hope = prefix[i] - need

    if (valToIdx.has(hope)) {
      res = Math.max(res, i - valToIdx.get(hope))
    }

    // 将出现次数记录进哈希表
    if (!valToIdx.has(prefix[i])) {
      valToIdx.set(prefix[i], i)
    }
  }

  return res === -1 ? -1 : nums.length - res
};